package com.zxy.supplier_system.server.repository

import com.zxy.supplier_system.server.entity.Market
import com.zxy.supplier_system.server.entity.MarketDeliveryOrder
import com.zxy.supplier_system.server.entity.MarketDeliveryOrderItem
import com.zxy.supplier_system.server.entity.SystemService
import com.zxy.supplier_system.server.utils.SpecificationUtils
import com.zxy.supplier_system.server.utils.joinOnce
import org.springframework.data.domain.Page
import org.springframework.data.domain.Pageable
import org.springframework.data.jpa.domain.Specification
import org.springframework.data.jpa.repository.JpaRepository
import java.time.LocalDate

@Suppress("FunctionName")
interface MarketDeliveryOrderItemRepository : JpaRepository<MarketDeliveryOrderItem, Int> {

    fun findAllByOrder_IdOrderBySequence(marketDeliveryOrder_id: Int, pageable: Pageable): Page<MarketDeliveryOrderItem>

    fun findByOrder_IdAndGoods_IdAndGoods_SystemService(
        order_id: Int,
        goods_id: Int,
        goods_systemService: SystemService
    ): MarketDeliveryOrderItem?

    fun existsByOrder_IdAndGoods_Id(marketDeliveryOrder_id: Int, goods_id: Int): Boolean

    fun existsByOrder_IdAndGoods_Barcode(marketDeliveryOrder_id: Int, goods_barcode: String): Boolean;

    fun findFirstByOrder_Market_IdAndGoods_IdOrderByOrder_CreatedDateTimeDesc(
        market_id: Int,
        goods_id: Int
    ): MarketDeliveryOrderItem?

    fun findByOrder_IdAndGoods_IdAndSubGoods_IdAndGoods_SystemService(
        id: Int,
        goods_id: Int,
        subGoods_id: Int?,
        systemService: SystemService
    ): MarketDeliveryOrderItem?

    object Specifications {
        fun orderCreatedDateTimeGreaterThanOrEqualTo(startDate: LocalDate?): Specification<MarketDeliveryOrderItem> {
            if (startDate == null) return SpecificationUtils.empty()
            return Specification { root, _, criteriaBuilder ->
                criteriaBuilder.greaterThanOrEqualTo(
                    root.joinOnce<MarketDeliveryOrderItem, MarketDeliveryOrder>("order").get("createdDateTime"),
                    startDate
                )
            }
        }

        fun orderCreatedDateTimeLessThan(endDate: LocalDate?): Specification<MarketDeliveryOrderItem> {
            if (endDate == null) return SpecificationUtils.empty()
            return Specification { root, _, criteriaBuilder ->
                criteriaBuilder.lessThan(
                    root.joinOnce<MarketDeliveryOrderItem, MarketDeliveryOrder>("order").get("createdDateTime"), endDate
                )
            }
        }

        fun goodsBrandIn(brandIds: List<Int>): Specification<MarketDeliveryOrderItem> {
            return GoodsRepository.Specifications.brandIn(brandIds) {
                it.joinOnce("goods")
            }
        }

        fun systemServiceEquals(systemService: SystemService): Specification<MarketDeliveryOrderItem> {
            return SystemServiceRepository.Specifications.systemServiceEquals({ r ->
                r.joinOnce<MarketDeliveryOrderItem, MarketDeliveryOrder>(
                    "order"
                ).joinOnce<MarketDeliveryOrder, Market>("market")
            }, systemService)
        }
    }

}

